package com.nidu.demo.user.gatewayimpl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nidu.demo.user.convertor.UserPositionConvertor;
import com.nidu.demo.user.gateway.UserPositionGateway;
import com.nidu.demo.user.mapper.UserPositionMapper;
import com.nidu.demo.user.mapper.dataobject.UserPositionDO;
import com.nidu.demo.user.model.UserPosition;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class UserPositionGatewayImpl implements UserPositionGateway {

    private final UserPositionMapper mapper;

    private final UserPositionConvertor convertor;

    @Override
    public void bindUserPosts(Long userId, Set<Long> postIds) {
        List<UserPosition> bindings = postIds.stream()
                .map(postId -> UserPosition.create(userId, postId))
                .collect(Collectors.toList());
        mapper.insert(convertor.toDataObjects(bindings));
    }

    @Override
    public void rebindUserPosts(Long userId, Set<Long> postIds) {
        removeUserPosts(userId);
        bindUserPosts(userId, postIds);
    }

    @Override
    public void removeUserPosts(Long userId) {
        LambdaQueryWrapper<UserPositionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPositionDO::getUserId, userId);
        mapper.delete(wrapper);
    }

    @Override
    public void removePostUsers(Long postId) {
        LambdaQueryWrapper<UserPositionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPositionDO::getPostId, postId);
        mapper.delete(wrapper);
    }

    @Override
    public void removeUsersPosts(Set<Long> userIds) {
        LambdaQueryWrapper<UserPositionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPositionDO::getUserId, userIds);
        mapper.delete(wrapper);
    }

    @Override
    public void removePostsUsers(Set<Long> postIds) {
        LambdaQueryWrapper<UserPositionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPositionDO::getPostId, postIds);
        mapper.delete(wrapper);
    }

    @Override
    public Set<Long> getPostIdsByUserId(Long userId) {
        LambdaQueryWrapper<UserPositionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPositionDO::getUserId, userId);
        List<UserPositionDO> positionDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(positionDOS)) {
            return new HashSet<>();
        }
        return positionDOS.stream().map(UserPositionDO::getPostId).collect(Collectors.toSet());
    }

    @Override
    public Set<Long> getUserIdsByPostId(Long postId) {
        LambdaQueryWrapper<UserPositionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPositionDO::getPostId, postId);
        List<UserPositionDO> positionDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(positionDOS)) {
            return new HashSet<>();
        }
        return positionDOS.stream().map(UserPositionDO::getUserId).collect(Collectors.toSet());
    }

    @Override
    public Map<Long, List<UserPosition>> getByUserIds(Set<Long> userIds) {
        LambdaQueryWrapper<UserPositionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserPositionDO::getUserId, userIds);
        List<UserPositionDO> roleDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(roleDOS)) {
            return Collections.emptyMap();
        }
        List<UserPosition> UserPositions = convertor.toDomainObjects(roleDOS);
        return UserPositions.stream().collect(Collectors.groupingBy(UserPosition::getUserId));
    }

    @Override
    public Map<Long, List<UserPosition>> getByPostIds(Set<Long> postIds) {
        LambdaQueryWrapper<UserPositionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserPositionDO::getPostId, postIds);
        List<UserPositionDO> roleDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(roleDOS)) {
            return Collections.emptyMap();
        }
        List<UserPosition> UserPositions = convertor.toDomainObjects(roleDOS);
        return UserPositions.stream().collect(Collectors.groupingBy(UserPosition::getUserId));
    }

}
